﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.Windows.Controls;
using System.Drawing;
using System.Windows;
using System.Reflection;
using System.IO;

namespace WpfReservedWords
{
    class Program
    {
        /*
         * This program walks the WPF CLR tree to generate the dictionary of casing corrections necessary because of Firefox
         * and Chrome poor support for XML.  Generates a string in C# array initializer format for inclusion in Filters.cs in Silverjax.App.
         * 
         * To use this program, you must first check out filtersReserved.cs in Silverjax, and make sure filename path below points to that file.
         * 
         * When you run this program, it will overwrite filtersReserved.cs.  You don't need to run this program every time you build; only
         * if you want to change the list of reserved words.
         * 
         * 
         *   */

        static void Main(string[] args)
        {

            Assembly assem = typeof(Button).Assembly;
            Assembly assem2 = typeof(Colors).Assembly;
            Assembly assem3 = typeof(FontWeights).Assembly;
            Assembly assem4 = typeof(System.Drawing.FontStyle).Assembly;

            
            string filename = @"c:\data\code\tribe\gestalt\gestalt\gestutil\filters\filtersReserved.cs";

            var types = assem.GetTypes().Concat(assem2.GetTypes()).Concat(assem3.GetTypes()).Concat(assem4.GetTypes());

            string[] namespaces = { "System.Windows.Controls", "System.Windows.Media", "System.Windows.Media.Animation", "System.Drawing", "System.Windows", "System.Windows.Shapes" };

            var filtered = from type in types
                           where namespaces.Contains(type.Namespace)
                           && (type.IsPublic && (type.IsClass || type.IsEnum))
                           select type;



            var allTypes = filtered;

            var memberNames = from type in allTypes
                              from member in type.GetMembers()
                              where member.MemberType == MemberTypes.Event || member.MemberType == MemberTypes.Field || member.MemberType == MemberTypes.Property
                              select member.Name;

            var typeNames = from type in allTypes select type.Name;

            var allnames = from name in memberNames.Concat(typeNames).Distinct() where needsFixing(name) orderby name select name;


            WriteFile(filename, allnames);
        }

        static bool needsFixing(string name)
        {
            // we only need to fix a name if it has more than one capitalized letter
            if (name.Length == 1) return false;
            string tail = name.Substring(1, name.Length - 1);
            if (tail.ToLower() == tail) return false;


            return true;
        }

        static void WriteFile(string filename, IEnumerable<string> words)
        {
            string header = @"
namespace Gestalt
{
    public partial class Filters
    {
            private string[] ReservedWords(){
                string[] xaml = new string[]
                {
";
            string footer = @"
                };
                return xaml;
            }
    }
}";
            var os = File.OpenWrite(filename);
            TextWriter tw = new StreamWriter(os);
            tw.WriteLine(header);

            tw.Write("\"" + words.First() + "\"");
            foreach (string w in words.Skip(1))
                tw.Write(",\r\n\"" + w + "\"");
            tw.WriteLine();
            tw.WriteLine(footer);
            tw.Close();
            return;

        }
    }
}
